### "Allegiance, Ability, and Achievement in the American Civil War: 
### Commander Traits and Battlefield Military Effectiveness"

### By Jeffrey B. Arnold, J. Tyson Chatagnier, and Gary E. Hollibaugh, Jr.

##### MOVING AVERAGES CODE TO GENERATE AVERAGE TRAITS OVER TIME.
##### DO NOT CALL THIS FILE DIRECTLY.


# Load data by time
library(lubridate)
corps <- read.csv(file.path(DIR_DATA, "ACH-CommandersCorps.csv"))

# Create date range grid and note when certain generals died
daterange <- data.frame(date = seq.Date(from=range(all_gens$edate)[1], to = range(all_gens$edate)[2], by = 1))
corps$date <- as.Date(corps$date, format = "%m/%d/%Y", origin = "1970-01-01")
corps$died <- as.Date(corps$died, format = "%m/%d/%Y", origin = "1970-01-01")
year(corps$died[which(year(corps$died) < 1800)]) <- year(corps$died[which(year(corps$died) < 1800)]) + 1900
year(corps$date[which(year(corps$date) < 1800)]) <- year(corps$date[which(year(corps$date) < 1800)]) + 1900

# Create timeline of activity for each commander
generals_timeline <- NULL
for(i in 1:length(unique(corps$comm_id))){
	foo <- corps[corps$comm_id == unique(corps$comm_id)[i],]
	foo <- foo[!is.na(foo$date),]
		if((sum(!is.finite(foo$date)) == 0) & (length(foo$date) > 0)){
			foo <- merge(foo, daterange, all = T)

			# trim top 
      foo <- foo[min(which(!is.na(foo$comm_id))):length(foo$comm_id),]
            
			# trim post-death dates
			foo <- subset(foo, date <= na.omit(unique(foo$died)))
			foo <- subset(foo, date <= max(daterange$date))

			for(j in 1:length(foo$comm_id)){
			if(is.na(foo$comm_id[j]) == TRUE){foo[j,] <- foo[j-1,]; foo$date[j] <- foo$date[j]+1}
			}

			# trim activity (retire, resign, MOV, etc.) dates
			foo <- (if(length(which(foo$resign == 1) > 0)){foo[-c(which(foo$resign == 1)),]} else{foo})
			foo <- (if(length(which(foo$retire == 1) > 0)){foo[-c(which(foo$retire == 1)),]} else{foo})
			foo <- (if(length(which(foo$cashiered == 1) > 0)){foo[-c(which(foo$cashiered == 1)),]} else{foo})
			foo <- (if(length(which(foo$dismissed == 1) > 0)){foo[-c(which(foo$dismissed == 1)),]} else{foo})
			foo <- (if(length(which(foo$MOV == 1) > 0)){foo[-c(which(foo$MOV == 1)),]} else{foo})
			foo <- (if(length(which(foo$discharged == 1) > 0)){foo[-c(which(foo$discharged == 1)),]} else{foo})
			} else{foo <- NULL}
		generals_timeline <- rbind(generals_timeline, foo)	
		}

# Trim timeline to be constrained within the ACW dates		
generals_timeline <- generals_timeline[generals_timeline$date %in% daterange$date,]
generals_timeline$comm_id <- as.character(generals_timeline$comm_id)

# Incorporate loyalty and competence data into general-specific timelines
gens_trim <- all_gens[,c('comm_id', 'edate2','comp','newloyal')]		
colnames(gens_trim)[2] <- "date"
merged_gen_timeline <- merge(gens_trim, generals_timeline, all = T)

# Expand commander timelines to day by day
foo2 <- merged_gen_timeline
for(i in 2:dim(foo2)[1]){
	if((is.na(foo2$newloyal[i]) == TRUE) & (foo2$comm_id[i] == foo2$comm_id[i - 1])){
	  foo2$newloyal[i] <- foo2$newloyal[i-1]; foo2$comp[i] <- foo2$comp[i-1]}
}

# Subset timelines to focus on commanding officers
foo3 <- foo2[which((foo2$rank %in% c("Col.", "Brig. Gen.", "Maj. Gen.", "Lt. Gen.", "Gen.", 
                                     "Adm.", "Vice Adm.", "Rear Adm.", "Comm.")) | 
                     (foo2$rank == "Capt." & foo2$army %in% c("U.S.N.", "C.S.N."))),]

# Drop missing data
foo3 <- foo3[!is.na(foo3$newloyal),]
foo3 <- foo3[!is.na(foo3$comp),]
foo3 <- foo3[!is.na(foo3$rank),]
foo3$Side <- 0
foo3$Side[grep("CS", foo3$comm_id)] <- 1
foo3$Side <- factor(foo3$Side, labels = c("Union", "Confederacy"))

# Subset into low and high ranks
foo3_low <- foo3[-which(foo3$rank %in% c("Maj. Gen.", "Lt. Gen.", "Gen.", "Adm.", "Vice Adm.", "Rear Adm.")),]
foo3_high <- foo3[which(foo3$rank %in% c("Maj. Gen.", "Lt. Gen.", "Gen.", "Adm.", "Vice Adm.", "Rear Adm.")),]

# Median traits by date
movavg_frame_high <- cbind(data.frame(with(foo3_high, aggregate(comp, by = list(Side, date), median, na.rm = TRUE))),
                           data.frame(with(foo3_high, aggregate(newloyal, by = list(Side, date), median, na.rm = TRUE)))[,3])
movavg_frame_low <- cbind(data.frame(with(foo3_low, aggregate(comp, by = list(Side, date), median, na.rm = TRUE))),
                          data.frame(with(foo3_low, aggregate(newloyal, by = list(Side, date), median, na.rm = TRUE)))[,3])

# Column names
colnames(movavg_frame_high) <- c("Side", "Date", "Competence", "Loyalty")
colnames(movavg_frame_low) <- c("Side", "Date", "Competence", "Loyalty")

# Differences between armies for low-ranking and high-ranking commanders, separated by traits
diff.comp.frame.high <- merge(subset(movavg_frame_high[,-4], Side == "Union"), 
                              subset(movavg_frame_high[,-4], Side == "Confederacy"), 
                              by = "Date")
diff.comp.frame.low <- merge(subset(movavg_frame_low[,-4], Side == "Union"), 
                             subset(movavg_frame_low[,-4], Side == "Confederacy"), 
                             by = "Date")

diff.comp.frame.high$Difference <- diff.comp.frame.high$Competence.y - diff.comp.frame.high$Competence.x
diff.comp.frame.low$Difference <- diff.comp.frame.low$Competence.y - diff.comp.frame.low$Competence.x

diff.loyal.frame.high <- merge(subset(movavg_frame_high[,-3], Side == "Union"), 
                               subset(movavg_frame_high[,-3], Side == "Confederacy"), 
                               by = "Date")

diff.loyal.frame.low <- merge(subset(movavg_frame_low[,-3], Side == "Union"), 
                              subset(movavg_frame_low[,-3], Side == "Confederacy"), 
                              by = "Date")

diff.loyal.frame.high$Difference <- diff.loyal.frame.high$Loyalty.y - diff.loyal.frame.high$Loyalty.x
diff.loyal.frame.low$Difference <- diff.loyal.frame.low$Loyalty.y - diff.loyal.frame.low$Loyalty.x


movavg_frame <- cbind(data.frame(with(foo3, aggregate(comp, by = list(Side, date), median, na.rm = TRUE))),
                      data.frame(with(foo3, aggregate(newloyal, by = list(Side, date), median, na.rm = TRUE)))[,3])

colnames(movavg_frame) <- c("Side", "Date", "Competence", "Loyalty")


diff.comp.frame <- merge(subset(movavg_frame[,-4], Side == "Union"), 
                         subset(movavg_frame[,-4], Side == "Confederacy"), 
                         by = "Date")

diff.comp.frame$Difference <- diff.comp.frame$Competence.y - diff.comp.frame$Competence.x

diff.loyal.frame <- merge(subset(movavg_frame[,-3], Side == "Union"), 
                          subset(movavg_frame[,-3], Side == "Confederacy"), 
                          by = "Date")

diff.loyal.frame$Difference <- diff.loyal.frame$Loyalty.y - diff.loyal.frame$Loyalty.x


diff.comp.frame.both <- rbind(data.frame(diff.comp.frame.high, Type = "High-Ranking Commanders"),
                              data.frame(diff.comp.frame.low, Type = "Brigadier Generals, Colonels, and Commodores"))

# Figure 1
comp_movavg_plot <- ggplot(diff.comp.frame.both, aes(x = Date, y = Difference)) + 
  geom_point(alpha = 0.025) +
  stat_smooth(method = "loess", colour = "black", alpha = 0.6, level = 0.95) + 
  scale_fill_manual(values = alpha(c("grey20", "grey80"), 0.6)) + 
  theme_bw() + 
  facet_wrap(~Type, ncol = 1, scales = "free_y") + 
  ylab("Confederate Advantage in Commander Competence\n") + 
  xlab("\nDate") + 
  scale_x_date(date_breaks = "3 months") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) + 
  geom_hline(yintercept = 0, linetype = "dotted")

ggsave(file.path(DIR_FIGURES, "ACH-Figure-1.eps"), 
       device = cairo_ps,
       comp_movavg_plot, height=4.875, width=6.5)

